<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Set 实例的属性和方法</title>
</head>

<body>
  <script>
    /*
      属性
      1. Set.prototype.constructor: 构造函数，默认是Set
      2. Set.prototype.size: 返回Set实例的成员个数

      Set方法类型
        1. 操作方法(用于操作数据)
          a: add(value): 添加某一值，返回Set结构本身
          b: delete(value): 删除某一值，返回布尔值，表示删除是否成功
          c: has(value): 返回布尔值，表示该值是否为Set的成员
          d: clear():清除所有的成员，没有返回值
        2. 遍历操作(用于遍历成员)
          a: keys(): 返回键名的遍历器
          b: values(): 返回键值的遍历器
          c: entries(): 返回键值对的遍历器
          d: forEach(): 返回回调函数遍历每一个成员
    */
    // -------------- 操作方法(用于操作数据) --------------------\\
    // let set = new Set()
    // // 已经被添加的不能重复添加
    // set.add(1).add(2).add(2)
    // console.log(set)//Set {1, 2}
    // console.log(set.delete(2))//true
    // console.log(set.delete(4))//false
    // console.log(set.has(1))//true

    // ----- 对比Object结构和Set结构 -----\\
    // // 对象的写法
    // const properties = {
    //   width: 1,
    //   height: 2
    // }
    // if(properties[someName]) {
    //   // 执行某些操作
    // }

    // // Set写法
    // const setProperties = new Set()
    // setProperties.add('width')
    // setProperties.add('height')
    // if(setProperties.has(someName)){
    //   // 执行某些操作
    // }

    // ----- 数组排序去重 -----\\
    // Array.from可以将Set结构转化为数组
    // const item = new Set([1,2,3,6,5,10,6])
    // let arr = Array.from(item)//返回数组
    // arr.sort((a,b) => {return a-b})
    // console.log(arr)//[1, 2, 3, 5, 6, 10]

    // ----------------------- 遍历操作 --------------- \\
    // // 1. keys()，values()，entries()
    // let set = new Set(['red', 'green', 'blue'])
    // for (const item of set.keys()) {
    //   console.log(item)
    // }//red green blue 返回键名

    // for (const item of set.values()) {
    //   console.log(item)
    // }//red green blue  返回值

    // for (const item of set.entries()) {
    //   console.log(item)
    // }//返回对象数组
    // // ["red", "red"]
    // // ["green", "green"]
    // // ["blue", "blue"]

    // // Set结构默认可遍历，它的默认遍历器生成函数是它的values方法
    // console.log(Set.prototype[Symbol.iterator] === Set.prototype.values) //true

    // 2. forEach()
    // let set = new Set([1,4,9])
    // set.forEach((value, key) => console.log(value,key))
    // // 1,1
    // // 4,4
    // // 9,9

    // 3.遍历的应用
    // - 扩展运算符（...）内部使用的是for....of循环，所以也可以使用Set结构
    // let set = new Set(['red', 'green', 'black', 'red'])
    // let arr = [...set]
    // console.log(arr) //["red", "green", "black"]

    // 2018-11-6

    // 数组中的map和filter方法也可以间接用于Set
    // let set = new Set([1,2,3,4,3,2])
    // set = new Set([...set].map((x) => {
    //   return x * 2
    // }))
    // // map方法返回一个新的数组
    // console.log(set) //Set(4) {2, 4, 6, 8}

    // filter方法
    // set = new Set([...set].filter(x => (x % 2) === 0))
    // console.log(set)


    // 使用Set可以更好的实现并集、交集和差集
    // let a = new Set([1,2,3])
    // let b = new Set([2,3,4])
    // // 并集
    // let union = new Set([...a, ...b])
    // console.log(union) //Set {1, 2, 3, 4}

    // // 交集
    // let intersect  = new Set([...a].filter(x => b.has(x)))
    // console.log(intersect)//Set {2, 3}

    // // 差集
    // let difference = new Set([...a].filter(x => !b.has(x)))
    // console.log(difference)//Set {1}


    // 改变原来的Set结构
    // 1. 利用原Set结构映射出一个新的结构，然后赋值给原来的Set结构
    // 2. 使用Array.from方法

    // 1
    let set = new Set([1, 2, 3])
    set = new Set([...set].map(x => x * 2))
    console.log(set) //Set{2,4,6}

    // 2
    set = new Set(Array.from(set, val => val * 2))
    console.log(set) //Set {4, 8, 12}
  </script>
</body>

</html>